﻿#pragma once
#include<QObject>
#include<QtGlobal>

//--------------------------静态方法---------------------------------------
///判断传入的值是否相等
template <typename T>
struct Compare;


template <typename T>
struct Compare{
    static bool IsEqual(const T & A ,const T & B ){
        return A == B;
    }
};

template <>
struct Compare<float>{
    static bool IsEqual(const float & A, const float &B){
        return  qFuzzyCompare(A,B);
    }
};

template <>
struct Compare<double>{
    static bool IsEqual(const double & A, const double &B){
        return  qFuzzyCompare(A,B);
    }
};








//-------------------------封装---------------------------------------------

///该封装用于单纯的修改属性
#define Mem(T, Name, Val)       T m_##Name = Val;

#define Get(T, Name)                                                                                         \
    const T &Name() const  {                                                                               \
        return     m_##Name;                                                                                  \
}

#define Set(T, Name)                                                                                           \
    void set##Name(const T & Val){                                                                     \
        m_##Name = Val;                                                                                         \
}

//读写
#define  AutoMem(T,Name,Val)                                                                         \
public :                                                                                                                   \
    Get(T,Name);                                                                                                     \
    Set(T,Name);                                                                                                      \
private :                                                                                                                  \
    Mem(T,Name,Val)

//只读
#define ReadOnlyMem(T,Name,Val)                                                                 \
public :                                                                                                                   \
    Get(T,Name);                                                                                                     \
private :                                                                                                                  \
    Mem(T,Name,Val)




/// 该封装用于Qt的元对象系统
#define Q_Prop_Get(T,Name)                                                                              \
    const T & Name()const {                                                                                   \
        return m_##Name;                                                                                         \
}

#define Q_Signal_Prop_Change(T,Name)                   Q_SIGNAL void Name##Changed(const T& value);

#define Q_Prop_Set(T,Name)                                                                              \
    void set##Name(const T & value)  {                                                                \
        if(Compare<T>::IsEqual(m_##Name,value) ) return;                                  \
         m_##Name = value;                                                                                      \
    emit Name##Changed(value);                                                                          \
}

//读写元对象
#define  Q_AutoProp(T,Name,Val)                                                                         \
    Q_PROPERTY(T Name READ Name WRITE set##Name NOTIFY Name##Changed)           \
public :                                                                                                                      \
        Q_Prop_Get(T,Name);                                                                                      \
        Q_SLOT Q_Prop_Set(T,Name);                                                                         \
        Q_Signal_Prop_Change(T,Name)                                                                    \
private:                                                                                                                       \
        Mem(T,Name,Val)

//只读元对象
#define Q_ReadOnlyProp(T,Name,Val)                                                                  \
       Q_PROPERTY(T Name READ Name CONSTANT)                                           \
public:                                                                                                                         \
       Q_Prop_Get(T,Name)                                                                                          \
private:                                                                                                                         \
        Mem(T, Name, Val)

//带有信号的读
#define    Q_ReadableProp(T,Name,Val)                                                                 \
    Q_PROPERTY(T Name READ Name NOTIFY Name##Changed)                      \
public:                                                                                                                         \
    Q_Prop_Get(T,Name)                                                                                             \
    Q_SLOT Q_Prop_Set(T,Name);                                                                               \
    Q_Signal_Prop_Change(T,Name)                                                                          \
private:                                                                                                                          \
     Mem(T, Name, Val)

